package gui;


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.skin.OfficeBlue2007Skin;

import assembler.GeneradorAssembler;

import parseador.Parser;
import parseador.TareasParser;

import filtros.ExtensionFileFilter;
import fuentes.AnalizadorLexico;
import fuentes.Fuente;
import fuentes.Mensajes;
import fuentes.TablaSimbolos;
import fuentes.Terceto;



/**
 * Crea y administra la ventana gr�fica principal que es utilizada para
 * la interacci�n con el usuario.
 *
 */ 

public class MainFrame extends JFrame implements ActionListener  {

	
	int iniAncho;
	int iniAlto;
	int insetArriba;
	int insetIzqda;
	public static JTextArea t1, t2, t3;
	JTextField resultado;
	static AnalizadorLexico Al;
	static Parser parser;
	String path;
	Color col;
	  
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private JPanel contentPane;
	private JPanel compilerPane;
	private JPanel simbolPane;
	private JPanel reservedPane;
	private JPanel titleCPane;
	private JPanel titleSPane;
	private JPanel titleRPane;
	private JToolBar toolBar;
	private Editor edit;
	private JMenuItem MAEditor;
	private JTabbedPane tabbedPane;
	private JLabel compiler=new JLabel("Salida del Compilador");
	private JLabel simbolos=new JLabel("Tabla de Simbolos");;
	private JLabel reserved=new JLabel("Codigo Intermedio: Tercetos");;

	private SkinManager diferentesSkins;
	

	



	
	
	
	/**
	 * Ejecuta la ventana principal, seleccionando un skin por defecto.
	 */
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				try {
					JFrame.setDefaultLookAndFeelDecorated(true);
					JDialog.setDefaultLookAndFeelDecorated(true);
					SubstanceLookAndFeel.setSkin(new OfficeBlue2007Skin());
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}
	

	/**
	 * Constructor, se crea la ventana y se a�aden todas las opciones de la misma.
	 * @throws InterruptedException 
	 * @throws IOException 
	 * @throws CorruptIndexException 
	 */

	public MainFrame() throws InterruptedException, IOException {
	
		path="";
		Font f = new Font ("Dialog",Font.BOLD,12);
		setTitle("Dise�o de Compiladores I UNCPBA");
		setIconImage(new ImageIcon(this.getClass().getResource("/Imagenes/unicen.gif")).getImage()); 
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setExtendedState(MAXIMIZED_BOTH);
		setFont(f);
		diferentesSkins = new SkinManager();
		
		JMenuBar menuBar = new JMenuBar();
		menuBar.setFont(f);
		setJMenuBar(menuBar);
		
		// Menu archivo
		JMenu MenuArchivo = new JMenu("Archivo");
		MenuArchivo.setFont(f);
		menuBar.add(MenuArchivo);
		
		JMenuItem MAAbrir = new JMenuItem("Generar Assembler");
		MAAbrir.setFont(f);
		MenuArchivo.add(MAAbrir);
		MAAbrir.setActionCommand("Generar Assembler");
		MAAbrir.addActionListener(this);
		MAAbrir.setIcon(new ImageIcon(this.getClass().getResource("/Imagenes/open.png")));
		
		JMenu MenuEditor = new JMenu("Editor");
		MenuEditor.setFont(f);
		menuBar.add(MenuEditor);
		
		MAEditor = new JMenuItem("Generar Assembler");
		MAEditor.setFont(f);
		MenuEditor.add(MAEditor);
		MAEditor.setActionCommand("Editor");
		MAEditor.addActionListener(this);
		MAEditor.setIcon(new ImageIcon(this.getClass().getResource("/Imagenes/editor.png")));
		
		JMenuItem MASalir = new JMenuItem("Salir");
		MASalir.setFont(f);
		MenuArchivo.add(MASalir);
		MASalir.setActionCommand("Salir");
		MASalir.addActionListener(this);
		MASalir.setIcon(new ImageIcon(this.getClass().getResource("/Imagenes/close.png")));
		//Fin Menu archivo
		
		
		//Menu ventana
		JMenu menuVentana = new JMenu("Ventana");
		menuVentana.setFont(f);
		menuBar.add(menuVentana);
		
		JMenu subCambiarSkin = new JMenu("Cambiar Skin");
		subCambiarSkin.setFont(f);
		menuVentana.add(subCambiarSkin);
		subCambiarSkin.setIcon(new ImageIcon(this.getClass().getResource("/Imagenes/skin.png"))); 
		//A�adimos todos los skins existentes...
		List<String> nombresSkins = diferentesSkins.nombresSkins();
		for (String skin : nombresSkins) {
			JMenuItem cambiarSkin = new JMenuItem(skin);
			cambiarSkin.setFont(f);
			subCambiarSkin.add(cambiarSkin);
			cambiarSkin.setActionCommand(skin);
			cambiarSkin.addActionListener(this);
		}
		//Fin Menu Ventana
		
		//Menu Ayuda
		JMenu menuAyuda = new JMenu("Ayuda");
		menuAyuda.setFont(f);
		menuBar.add(menuAyuda);
		
		JMenuItem MAyAcerca = new JMenuItem("Acerca de...");
		MAyAcerca.setFont(f);
		menuAyuda.add(MAyAcerca);
		MAyAcerca.setIcon(new ImageIcon(this.getClass().getResource("/Imagenes/help.png")));
		MAyAcerca.setActionCommand("Menu Acerca");
		MAyAcerca.addActionListener(this);
		
		//Fin Menu ayuda
		
		
		
		EmptyBorder c = new EmptyBorder(5, 5, 5, 5);
		contentPane = new JPanel();
		contentPane.setBorder(c);
		//getContentPane().add(contentPane);
		contentPane.setLayout(new BorderLayout());
		contentPane.setAutoscrolls(true);
	
		EmptyBorder b = new EmptyBorder(5, 10, 10, 10);
		
		//panel de titulos
		titleCPane=new JPanel();
		titleCPane.setBorder(b);
		titleSPane=new JPanel();
		titleSPane.setBorder(b);
		titleRPane=new JPanel();
		titleRPane.setBorder(b);
		
		//panel de salida de compilador
		compilerPane = new JPanel();
		compilerPane.setLayout(new BorderLayout());
		compilerPane.setAutoscrolls(true);
		
		//Area de Texto de la salida del compilador
		
	    t1 = new JTextArea( );
	    t1.setBorder(b);
	    t1.setForeground(Color.BLACK);
	    col=t1.getBackground();
	    t1.setEditable( false );
	    t1.setBorder(b);
	    t1.setFont(f);
	    t1.setSize(new Dimension(450, 0));
	    
	    //A�ado Area de Texto de la salida del compilador al panel compilerPane
	    compilerPane.add(t1, BorderLayout.CENTER);
	    JScrollPane scrollable1 = new JScrollPane(t1);
		scrollable1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollable1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		compilerPane.add( scrollable1,BorderLayout.CENTER);
		
		//A�ado al titleCPane el label
		compiler.setFont(f);
//		compiler.setSize(new Dimension(450, 15));
		titleCPane.add(compiler,BorderLayout.CENTER);
		
		//A�ado el panel del titulo
		compilerPane.add(titleCPane,BorderLayout.NORTH);
		
		//A�ado el panel compilerPane al panel contentPane
		contentPane.add(compilerPane,BorderLayout.WEST);
		
		//panel de salida de compilador
		simbolPane = new JPanel();
		simbolPane.setLayout(new BorderLayout());
		simbolPane.setAutoscrolls(true);
		

		
		//Area de Texto de la tabla de simbolos
	    t2 = new JTextArea( );
	    t2.setBorder(b);
	    t2.setForeground(Color.BLACK);
	    t2.setEditable( false );
	    t2.setBorder(b);
	    t2.setFont(f);
	    simbolPane.add(t2, BorderLayout.CENTER);
		JScrollPane scrollable2 = new JScrollPane(t2);
		scrollable2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollable2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		simbolPane.add( scrollable2,BorderLayout.CENTER);
		
		//A�ado al titleCPane el label
		simbolos.setFont(f);
		titleSPane.add(simbolos,BorderLayout.CENTER);
		
		//A�ado el panel del titulo
		simbolPane.add(titleSPane,BorderLayout.NORTH);
		
		//A�ado el panel simbolPane al panel contentPane
		contentPane.add(simbolPane,BorderLayout.CENTER);
		
		//panel de salida de compilador
		reservedPane = new JPanel();
		reservedPane.setLayout(new BorderLayout());
		reservedPane.setAutoscrolls(true);
		
		//Area de Texto de las palabras reservadas
	    t3 = new JTextArea();
	    t3.setBorder(b);
	    t3.setForeground(Color.BLACK);
	    t3.setEditable( false );
	    t3.setBorder(b);
	    t3.setFont(f);
	    reservedPane.add(t3, BorderLayout.CENTER);
	    JScrollPane scrollable3 = new JScrollPane(t3);
		scrollable3.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		scrollable3.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
		reservedPane.add( scrollable3,BorderLayout.CENTER);
		
		//A�ado al titleCPane el label
		reserved.setFont(f);
		titleRPane.add(reserved,BorderLayout.CENTER);
		
		//A�ado el panel del titulo
		reservedPane.add(titleRPane,BorderLayout.NORTH);
		
		//A�ado el panel reservedPane al panel contentPane
		contentPane.add(reservedPane,BorderLayout.EAST);
		
		//Fin Paneles de Texto
		
		//Area de resultado
		EmptyBorder r = new EmptyBorder(15, 15, 15, 15);
		resultado=new JTextField();
		resultado.setForeground(Color.BLACK);
		resultado.setBorder(r);
		resultado.setFont(f);
		resultado.setEditable(false);
		resultado.setHorizontalAlignment(JTextField.CENTER);
		contentPane.add(resultado,BorderLayout.SOUTH);

		
		
		toolBar = new JToolBar();
		toolBar.setFloatable(false);
		toolBar.setBounds(0, 0, 588, 31);
		contentPane.add(toolBar, BorderLayout.NORTH);
		
		tabbedPane = new JTabbedPane();
		tabbedPane.setFont(f);
		edit = new Editor();
		tabbedPane.addTab("Analizador", new ImageIcon(this.getClass().getResource("/Imagenes/open.png")), contentPane,"Muestra el resultado del An�lis");
		tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
		tabbedPane.addTab("Editor", new ImageIcon(this.getClass().getResource("/Imagenes/editor.png")), edit,"Editor de codigo fuente");
		tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
		
		getContentPane().add(tabbedPane);
		
		
		
		
	}

	
	public void actionPerformed(ActionEvent e) {
		JInternalFrame frame = new JInternalFrame();
		
		if (e.getActionCommand().equals("Generar Assembler"))
		{
			JFileChooser d=new JFileChooser();
       	 	ExtensionFileFilter filter1 =new ExtensionFileFilter("txt y TXT", new String[] { "txt", "TXT" });
            d.setFileFilter(filter1);
            
            if (!path.equals(""))
            	d.setCurrentDirectory(new File(path));
            
       	 	int result=d.showOpenDialog(this);
       	 
       	 	if (result==JFileChooser.APPROVE_OPTION)
       	 	{
       	 		resultado.setBackground(col);
       	 		t1.setText("");
       	 		t2.setText("");
       	 		t3.setText("");
       		 
       	 		path=d.getSelectedFile().getAbsolutePath().toString();
       	 		compilar(path);
       		 
       	 		Mensajes m=Mensajes.getInstance();
       	 		m.mostrar(t1);
       	 		m.limpiarMensajes();
       		             		 
       	 		TablaSimbolos tabla=TablaSimbolos.getInstance();
       	 		tabla.mostrarTablaSim(t2);
       	 		TareasParser.mostrarTercetos(t3);
       	 		tabla.vaciar();
       	 	}
		}
		else
			if (e.getActionCommand().equals("Editor"))
			{
				//mostrar editor
				recompilar();
			}
			else 
			if (e.getActionCommand().equals("Salir"))
			{
				System.out.println("Saliendo!");
				cerrarVentana();
			}
			else 
				if (e.getActionCommand().equals("Menu Acerca"))
				{
					frame.dispose();
					String mensaje="Dise�o de Compiladores I \n 1� Entrega 2010 \n Autores: \n Agust�n Burgos           agustinlburgos@gmail.com \n Juan Cruz Avellaneda       jcave777@hotmail.com \n Manuel Obregozo       obre41@gmail.com";
					JOptionPane.showMessageDialog(this,mensaje,"Acerca de...", JOptionPane.INFORMATION_MESSAGE);					
				}
				else
					if (diferentesSkins.getSkin(e.getActionCommand())!= null)
						SubstanceLookAndFeel.setSkin(diferentesSkins.getSkin(e.getActionCommand()));
	}
				
				
		public void recompilar(){
			Mensajes m=Mensajes.getInstance();
			TablaSimbolos tabla=TablaSimbolos.getInstance();
			m.limpiarMensajes();
			tabla.vaciar();

			resultado.setBackground(col);
   	 		t1.setText("");
   	 		t2.setText("");
   	 		t3.setText("");
   	 		Fuente.reciclarFuente(edit.getFuente(),"fuente.txt");
   	 		
   	 		compilar("fuente.txt");
   	 		m=Mensajes.getInstance();
	 		m.mostrar(t1);
	 		m.limpiarMensajes();
		             		 
	 		tabla=TablaSimbolos.getInstance();
	 		tabla.mostrarTablaSim(t2);
	 		//tabla.mostrarPalabrasRes(t3);
	 		TareasParser.mostrarTercetos(t3);
	 		tabla.vaciar();
			TareasParser.vector.clear();
		 	TareasParser.controlAmbitos.clear();
		 	TareasParser.controlDeclaraciones.clear();
		 	TareasParser.numAmbito=1;
		 	TareasParser.nroT=1;
		 	TareasParser.tercetos = new Vector<Terceto>();
		 	
	 		
	 		
		}
       	public int compilar(String path1) {
    		int retorna = 0;
       		tabbedPane.setSelectedIndex(0);
//    		TablaSimbolos tabla=TablaSimbolos.getInstance();
    		edit.setFuente(Fuente.getFuente(path1));
    		Al=new AnalizadorLexico(path1);
    		
    		parser=new Parser(false,Al);
//    		Mensajes m=Mensajes.getInstance();
    		if (parser.yyparse()==0)
    		{
    			
    			//GENERAR ASSEMBLER
    			//AGREGAR SOLICITUD DE GUARDADO DE CODIGO ASSEMBLER
    			JFileChooser fileChooser = new JFileChooser();
           	 	ExtensionFileFilter filter1 =new ExtensionFileFilter("asm y ASM", new String[] { "asm", "ASM" });
           	 	fileChooser.setFileFilter(filter1);
                
                if (!path.equals(""))
                	fileChooser.setCurrentDirectory(new File(path));
                
           	 	int result=fileChooser.showSaveDialog(this);
           	 
           	 	if (result==JFileChooser.APPROVE_OPTION)
           	 	{
           	 		path=fileChooser.getSelectedFile().getAbsolutePath().toString();
           	 	
           	 		if (!path.contains(".asm") && !path.contains(".ASM"))
           	 			path = path.concat(".asm");
           	 		
           	 		GeneradorAssembler genAsm = new GeneradorAssembler(TareasParser.tercetos,path);
           	 		try {
           	 			genAsm.generaCodigo();
           	 		} catch (IOException e) {
					// TODO Auto-generated catch block
           	 			e.printStackTrace();
           	 		}
           	 		
           	 		resultado.setText("Parseado con �xito!");
           	 		resultado.setBackground(Color.GREEN);
           	 	}
           	 	else
           	 	{
           	 	resultado.setText("Se cancel� la generaci�n de assembler!");
           	 	resultado.setBackground(Color.yellow);
           	 	JOptionPane.showMessageDialog(this,"No se gener� Assembler.","Operaci�n cancelada", JOptionPane.INFORMATION_MESSAGE);
           	 	
           	 	}
    		}
    		else
    		{
    			resultado.setText("Parseado con Errores!");
    			resultado.setBackground(Color.RED);
    		}
		
    		return retorna;
    	}

	
	private void cerrarVentana() {
		
			System.exit(EXIT_ON_CLOSE);
			
			}




	
   
}
